package seismosurfer.domain;

import java.io.IOException;
import java.io.PrintWriter;

import seismosurfer.data.QuakeClientData;
import seismosurfer.data.QuakeData;
import seismosurfer.util.SeismoException;
import seismosurfer.util.TimeUtil;

/**
 * The base class on which all data exporting is based.
 * The UI widgets can depend only on this class
 * for data exporting, as it has a factory method
 * ({@link #makeExport}) to instantiate the appropriate
 * implementation.
 *
 */
public abstract class Export {    
    
    /** The Comma-separated values file format */
    public static final int CSV = 0;
    
    /** The Excel Comma-separated values file format */
    public static final int EXCEL_CSV = 1;

    /** The Tab-separated values file format */
    public static final int TSV = 2;
    
    /** Keyhole Markup Language format used by Google Earth */
    public static final int KML = 3;
    
    /** The file extension for a particular file format */
    public abstract String getExtension();

    /** A description of the file format useful for a UI widget */
    public abstract String getDescription();
    
    /** Prints the data in the given output stream 
     * in the appropriate format.
     */
    public abstract void doExport(PrintWriter out) throws IOException;
    
    /**
     * A factory method that instantiates an
     * appropriate export object based on the
     * given file format type.
     * 
     * @param exportType the file format used for 
     *        data exporting
     * @return  an appropriate Export subclass object
     *          that corresponds to the given file format type
     */
    public static Export makeExport(int exportType) {
        Export exp = null;

        switch (exportType) {
        case CSV:
            exp = new CSVExport();
            break;
        case EXCEL_CSV:
            exp = new ExcelCSVExport();
            break;
        case TSV:
            exp = new TSVExport();
            break;
        default:
            throw new SeismoException("Export type is not supported");
        }

        return exp;
    }
    
    /**
     * Converts earthquake data into 
     * a two dimensional array string representation.
     * Each row of the array contains the data
     * for one earthquake.
     * 
     * @return a two dimensional array string representation
     *         of the earthquakes
     */
    public String[][] getQuakeData() {
        QuakesConverter t = new QuakesConverter();
        return t.getQuakeData();
    }
    
    /**
     * Earthquake data converter. Converts data
     * from an inner memory representation to
     * a text representation.
     *
     */
    public class QuakesConverter {

        public QuakesConverter() {
        }

        public String[][] getQuakeData() {
            java.util.List quakes = QuakeClientData.getQuakeResults();
            int size = quakes.size();

            String[][] result = new String[size + 1][7];

            result[0] = getQuakeHeaders();

            for (int i = 0; i < size; i++) {
                result[i + 1] = getQuakeRecord((QuakeData) quakes.get(i));
            }
            return result;
        }

        public String[] getQuakeRecord(QuakeData q) {

            String[] temp = new String[7];

            temp[0] = TimeUtil.toText(q.getDateTime());
            temp[1] = String.valueOf(q.getLatitude());
            temp[2] = String.valueOf(q.getLongitude());
            temp[3] = String.valueOf(q.getDepth());
            temp[4] = String.valueOf(q.getMagnitude());
            temp[5] = q.getCatalogName();
            temp[6] = q.getSource();

            return temp;
        }

        public String[] getQuakeHeaders() {
            String[] result = { "datetime", "lat", "long", "depth",
                    "magnitude(Ms)", "catalog", "source" };
            return result;
        }

    }

}